home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / p063b9s.zip / UNIT / TPAVATAR.PAS < prev    next >
Pascal/Delphi Source File  |  1996-04-20  |  11KB  |  350 lines

  1. Unit TpAvatar;                    { er jeg ikke opfindsom ? }
  2.  
  3.  { This is a unit for implementing Avatar control sequences conforming to   }
  4.  { AVT/0 in Turbo Pascal. The implementation is based on information        }
  5.  { available in the FSC-0025 and FSC-0037 docs.                             }
  6.  { Notes:                                                                   }
  7.  { Insert mode is not fully implemented as ^V^Y does not respect it. This   }
  8.  { will come at a later date.                                               }
  9.  
  10. Interface
  11.  
  12. Uses Use32, OpCrt, OpString;
  13. { As you can see, I have used two units from Turbo Power Professional (TPro)}
  14. { To a certain extent you can use Crt and PoorMan instead. The routines not }
  15. { present in the PoorMan unit you will have to implement yourself.          }
  16.  
  17. Const
  18.   DefaultColor   : Byte = Cyan;
  19.   InsertMode     : Boolean = False;
  20.  
  21. Procedure AvatarWrite(Ch : Char);
  22. Function In_Avatar : Boolean;
  23. Procedure ClearAvatarState;
  24.  
  25. Implementation
  26.  
  27. Type
  28.   States         = (Waiting, Whee, Gotcha, Rower, Columnizer,
  29.                     Yuck, YuckNum, ScrollNum, ScrollUpper,
  30.                     ScrollLeft, ScrollLower, ScrollRt, L1, L2, L3,
  31.                     M1, M2, M3, M4, Ynum, Ych, Ytimes);
  32.  
  33. Const
  34.   Up = True;
  35.   Down = False;
  36.  
  37. Var
  38.   Direction : Boolean;
  39.   NextState      : States;
  40.   WindLo, WindHi,
  41.   NextRow, NextColumn,
  42.   Num            : Word;
  43.   xlo, ylo,
  44.   xhi, yhi       : Byte;
  45.   RChar          : Char;
  46.  
  47.   St             : String;
  48.  
  49.   Procedure ClearAvatarState;
  50.   BEGIN
  51.     NextState:=Waiting;
  52.   END;
  53.  
  54.   Function In_Avatar : Boolean;
  55.   Begin
  56.     In_Avatar := NextState <> Waiting;
  57.   End {In_Avatar} ;
  58.  
  59.   Procedure AvatarWrite(Ch : Char);
  60.   Begin
  61.     Case NextState Of
  62.       Waiting :
  63.         Case Ch Of
  64.           ^V :
  65.             Begin
  66.               NextState := Whee;
  67.               InsertMode := False;
  68.             end;
  69.           ^Y : NextState := Yuck;
  70.           ^L :
  71.             Begin
  72.               TextAttr := DefaultColor;
  73.               InsertMode := False;
  74.               ClrScr;
  75.             end;
  76.           Else
  77.             If InsertMode And (WhereXAbs < Lo(WindMax)) then
  78.             Begin
  79. {
  80.               ReadAttributeWindow(Lo(WindMax)-WhereX, WhereY, WhereX, St2);
  81.               FastReadWindow(Lo(WindMax)-WhereX, WhereY, WhereX, St);
  82.               FastWriteWindow(Copy(Ch + St,1,Lo(WindMax)-WhereX+1), WhereY, WhereX,TextAttr);
  83.               WriteAttributeWindow(Copy(Chr(TextAttr)+ St2,1,Lo(WindMax)-WhereX+1), WhereY, WhereX);
  84. }
  85.             end
  86.             else Write(Ch);
  87.         End {Case} ;
  88.       Whee :
  89.         Begin
  90.           If Ch <> ^Y then InsertMode := False;
  91.           Case Ch Of
  92.             ^A :
  93.               Begin
  94.                 NextState := Gotcha;
  95.                 TextAttr := Ord(Ch);
  96.               End;
  97.             ^B :
  98.               Begin
  99.                 NextState := Waiting;
  100.                 TextAttr := TextAttr Or $80;
  101.               End;
  102.             ^C :
  103.               Begin
  104.                 NextState := Waiting;
  105.                 GotoXY(WhereX, WhereY - 1);
  106.               End;
  107.             ^D :
  108.               Begin
  109.                 NextState := Waiting;
  110.                 GotoXY(WhereX, WhereY + 1);
  111.               End;
  112.             ^E :
  113.               Begin
  114.                 NextState := Waiting;
  115.                 GotoXY(WhereX - 1, WhereY);
  116.               End;
  117.             ^F :
  118.               Begin
  119.                 NextState := Waiting;
  120.                 GotoXY(WhereX + 1, WhereY);
  121.               End;
  122.             ^G :
  123.               Begin
  124.                 NextState := Waiting;
  125.                 ClrEol;
  126.               End;
  127.             ^H :
  128.               NextState := Rower;
  129.             ^I :
  130.               Begin
  131.                 InsertMode := True;
  132.                 NextState := Waiting;
  133.               end;
  134.             ^J :
  135.               Begin
  136.                 Direction := Up;
  137.                 NextState := ScrollNum;
  138.               end;
  139.             ^K :
  140.               Begin
  141.                 Direction := Down;
  142.                 NextState := ScrollNum;
  143.               end;
  144.             ^L :
  145.               NextState := L1;
  146.             ^M :
  147.               NextState := M1;
  148.             ^N :
  149.               Begin
  150. {
  151.                 ReadAttributeWindow(Lo(WindMax)-WhereX, WhereY, WhereX+1, St2);
  152.                 FastReadWindow(Lo(WindMax)-WhereX, WhereY, WhereX+1, St);
  153.                 FastWriteWindow(St + ' ', WhereY, WhereX,TextAttr);
  154.                 WriteAttributeWindow(St2 + Chr(TextAttr), WhereY, WhereX);
  155. }
  156.               end;
  157.             ^Y :
  158.               NextState := Ynum;
  159.             Else
  160.               NextState := Waiting;
  161.               If InsertMode And (WhereXAbs < Lo(WindMax)) then
  162.               Begin
  163. {
  164.                 ReadAttributeWindow(Lo(WindMax)-WhereX, WhereY, WhereX, St2);
  165.                 FastReadWindow(Lo(WindMax)-WhereX, WhereY, WhereX, St);
  166.                 FastWriteWindow(Copy(Ch + St,1,Lo(WindMax)-WhereX+1), WhereY, WhereX,TextAttr);
  167.                 WriteAttributeWindow(Copy(Chr(TextAttr)+ St2,1,Lo(WindMax)-WhereX+1), WhereY, WhereX);
  168. }
  169.               end
  170.               else Write(Ch);
  171.           End {Case Ch} ;
  172.         End;
  173.       Gotcha :
  174.         Begin
  175.           NextState := Waiting;
  176.           TextAttr := Ord(Ch);
  177.         End;
  178.       Rower :
  179.         Begin
  180.           NextState := Columnizer;
  181.           NextRow := Ord(Ch);
  182.           If (NextRow < 1) Then NextRow := 1
  183.           Else
  184.             If (NextRow + Lo(WindMin) > Lo(WindMax) + 1)
  185.           Then NextRow := Lo(WindMax) - Lo(WindMin) + 1;
  186.         End;
  187.       Columnizer :
  188.         Begin
  189.           NextState := Waiting;
  190.           NextColumn := Ord(Ch);
  191.           If (NextColumn < 1) Then
  192.             NextColumn := 1
  193.           Else
  194.             If (NextColumn + Hi(WindMin) > Hi(WindMax) + 1) Then
  195.             NextColumn := Hi(WindMax) - Hi(WindMin) + 1;
  196.           GotoXY(NextColumn, NextRow);
  197.         End;
  198.       Yuck :
  199.         Begin
  200.           NextState := YuckNum;
  201.           RChar := Ch;
  202.         End;
  203.       YuckNum :
  204.         Begin
  205.           Num := Byte(Ch);
  206.           NextState := Waiting;
  207.           if InsertMode then
  208.           Begin
  209.             For xlo := 1 to Num do
  210.               if WhereXAbs < Lo(WindMax) then
  211.               Begin
  212. {
  213.                 ReadAttributeWindow(Lo(WindMax)-WhereX, WhereY, WhereX, St2);
  214.                 FastReadWindow(Lo(WindMax)-WhereX, WhereY, WhereX, St);
  215.                 FastWriteWindow(Copy(RChar + St,1,Lo(WindMax)-WhereX+1), WhereY, WhereX,TextAttr);
  216.                 WriteAttributeWindow(Copy(Chr(TextAttr)+ St2,1,Lo(WindMax)-WhereX+1), WhereY, WhereX);
  217. }
  218.               end
  219.             else Write(RChar);
  220.           end
  221.           else for xlo := 1 to num do Write(RChar);
  222.         End;
  223.       ScrollNum: { number of lines to scroll }
  224.         Begin
  225.           Num := Byte(Ch);
  226.           NextState := ScrollUpper;
  227.         end;
  228.       ScrollUpper : { Upper limit }
  229.         Begin
  230.           ylo := Byte(Ch);
  231.           NextState := ScrollLeft;
  232.         end;
  233.       ScrollLeft :
  234.         Begin
  235.           xlo := Byte(Ch);
  236.           NextState := ScrollLower;
  237.         end;
  238.       ScrollLower :
  239.         Begin
  240.           yhi := Byte(Ch);
  241.           NextState := ScrollRt;
  242.         end;
  243.       ScrollRt :
  244.         Begin
  245.           xhi := Byte(Ch);
  246.  
  247.           {clip coordinates and convert to absolute coordinates}
  248.  
  249.           if Xlo = 0 then Xlo := 1;
  250.           if Ylo = 0 then Ylo := 1;
  251.           if (Xhi > Lo(WindMax) - Lo(WindMin) + 1)
  252.           then Xhi := Lo(WindMax)
  253.           else Xhi := Lo(WindMin) + Xhi - 1;
  254.           if (Yhi > Hi(WindMax) - Hi(WindMin) + 1)
  255.           then Yhi := Hi(WindMax)
  256.           else Yhi := Hi(WindMin) + Yhi - 1;
  257.           xhi := xhi + Lo(WindMin) -1;
  258.           yhi := yhi + Hi(WindMin) -1;
  259.  
  260.           If Direction = Up
  261.           then OpCrt.ScrollWindowUp(xlo, ylo, xhi, yhi, num)
  262.           else OpCrt.ScrollWindowDown(xlo, ylo, xhi, yhi, num);
  263.           NextState := Waiting;
  264.         end;
  265.       L1 : { attribute to use }
  266.         Begin
  267.           TextAttr := Byte(Ch);
  268.           NextState := L2;
  269.         end;
  270.       L2 : { number of lines to clear }
  271.         Begin
  272.           num := Byte(Ch);
  273.           NextState := L3; { alternate: RChar := ' '; NextState := M4;}
  274.         end;               { (saves one state)                        }
  275.       L3 : { number of columns }
  276.         Begin
  277.           xhi := Byte(Ch);
  278.           xlo := Lo(WindMin) + WhereX -1;
  279.           ylo := Hi(WindMin) + WhereY -1;
  280.           xhi := Lo(WindMin) + xhi -1;
  281.           yhi := Hi(WindMin) + num -1;
  282.           if (Xhi > Lo(WindMax)) then Xhi := Lo(WindMax);
  283.           if (Yhi > Hi(WindMax)) then Yhi := Hi(WindMax);
  284.           num := 0;
  285.           OpCrt.ScrollWindowUp(xlo, ylo, xhi, yhi, num);
  286.           NextState := Waiting;
  287.         end;
  288.       M1 :
  289.         Begin
  290.           TextAttr := Byte(Ch);
  291.           NextState := M2;
  292.         end;
  293.       M2 :
  294.         Begin
  295.           RChar := Ch;
  296.           NextState := M3;
  297.         end;
  298.       M3 : { number of lines to clear }
  299.         Begin
  300.           num := Byte(Ch);
  301.           NextState := M4;
  302.         end;
  303.       M4 : { number of columns }
  304.         Begin
  305.           NextRow := Byte(Ch);
  306.           { convert to absolute coordinates }
  307.           xlo := Lo(WindMin) + WhereX -1;
  308.           ylo := Hi(WindMin) + WhereY -1;
  309.           xhi := Lo(WindMin) + NextRow -1;
  310.           yhi := Hi(WindMin) + num -1;
  311.           { clip to fit window }
  312.           if (Xhi > Lo(WindMax)) then Xhi := Lo(WindMax);
  313.           if (Yhi > Hi(WindMax)) then Yhi := Hi(WindMax);
  314.           { save current coordinates }
  315.           WindHi := windMax; WindLo := WindMin;
  316.           { fill desired area with desired char }
  317.           Window(xlo, ylo, xhi, yhi);
  318. {          FastFillwindow(NextRow * Num, RChar, 1, 1, TextAttr);}
  319.           { restore coordinates }
  320.           WindMax := WindHi; WindMin := WindLo;
  321.           NextState := Waiting;
  322.         end;
  323.       Ynum :
  324.         Begin
  325.           Num := Byte(Ch);
  326.           St := '';
  327.           NextState := Ych;
  328.         End;
  329.       Ych :
  330.         Begin
  331.           St := St + Ch;
  332.           Dec(num);
  333.           if Num = 0
  334.           then NextState := Ytimes
  335.           else NextState := Ych;
  336.         end;
  337.       Ytimes :
  338.         Begin
  339.           Xlo := Byte(Ch);
  340.           { expand string }
  341.           For xhi := 1 to xlo do Write(St);{ /// treat insertmode here /// }
  342.           NextState := Waiting;
  343.         end;
  344.     End {Case NextState} ;
  345.   End {AvatarWrite} ;
  346.  
  347. Begin
  348.   NextState := Waiting;
  349. End.
  350.